"""
@Author : 合肥一元数智教育科技有限公司
@Date :  2025/6/7 10:03
@Description : 
客户端
1. 窗口
2. socket
"""
import socket
import threading

import wx
from wx import Point, Size


class ChatClient(wx.Frame):
    def __init__(self):
        # socket 初始化
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 链接状态
        self.is_connected = False
        # 初始化窗口
        wx.Frame.__init__(self, None, title='python2512聊天室', size=Size(480, 680))
        self.panel = wx.Panel(self, size=Size(480, 680))
        """
         初始化四个按钮
         加入群聊
         离开群聊
         清空记录
         发送消息
        """
        self.add_chat_btn = wx.Button(self.panel, label='加入群聊', pos=Point(10, 10), size=Size(200, 40))
        self.leave_chat_btn = wx.Button(self.panel, label='离开群聊', pos=Point(250, 10), size=Size(200, 40))
        self.clear_message_btn = wx.Button(self.panel, label='清空记录', pos=Point(10, 580), size=Size(200, 40))
        self.send_message_btn = wx.Button(self.panel, label='发送消息', pos=Point(220, 580), size=Size(200, 40))

        """
         绑定四个按钮的事件
        """
        self.add_chat_btn.Bind(wx.EVT_BUTTON, self.add_chat)
        self.leave_chat_btn.Bind(wx.EVT_BUTTON, self.leave_chat)
        self.clear_message_btn.Bind(wx.EVT_BUTTON, self.clear_message)
        self.send_message_btn.Bind(wx.EVT_BUTTON, self.send_message)

        """
          1.输入框
          2.信息展示框
        """
        # 创建聊天内容文本框  多行信息和只读
        self.show_text = wx.TextCtrl(self.panel, size=Size(440, 400), pos=Point(10, 60),
                                     style=wx.TE_READONLY | wx.TE_MULTILINE)
        # 创建输入内容文本框
        self.input_text = wx.TextCtrl(self.panel, size=Size(440, 80), pos=Point(10, 470), style=wx.TE_MULTILINE)

    # 加入聊天室     连接服务器  开始接收服务端发送的信息
    def add_chat(self, event):
        if not self.is_connected:
            try:
                self.socket.connect(('127.0.0.1', 9999))
                self.show_text.AppendText('服务器连接成功了,开始聊天...\n')
                # 改变客户端的连接状态
                self.is_connected = True
                # 开始接收服务端发送的信息
                threading.Thread(target=self.recv_message).start()
            except ConnectionRefusedError as e:
                self.show_text.AppendText('服务器连接失败,请重新连接\n')

    # 离开聊天室
    def leave_chat(self, event):
        self.is_connected = False
        self.socket.close()

    # 清空信息
    def clear_message(self, event):
        self.show_text.Clear()

    # 发送信息
    def send_message(self, event):
        if self.is_connected:
            # 获取用户输入聊天信息
            user_message = self.input_text.GetValue()
            self.socket.send(user_message.encode('utf-8'))
            self.input_text.Clear()

    # 发送信息
    def recv_message(self):
        try:
            if self.is_connected:
                while True:
                    message = self.socket.recv(1024).decode('utf-8')
                    if message:
                        self.show_text.AppendText(message)
        except ConnectionAbortedError as e:
            self.show_text.AppendText('当前客户端离线...')
            self.is_connected = False
        except ConnectionResetError as e:
            self.show_text.AppendText('服务端异常,请重新连接...')
            self.is_connected = False


if __name__ == '__main__':
    app = wx.App()
    chat = ChatClient()
    chat.Show(True)
    app.MainLoop()
